package at.technikum_wien.embsys.aat.PriscillaCore.component;

import java.util.Iterator;
import java.util.List;

import at.technikum_wien.embsys.aat.PriscillaCore.enums.BinaryState;
import at.technikum_wien.embsys.aat.PriscillaCore.enums.EnoceanComponentType;
import at.technikum_wien.embsys.aat.PriscillaCore.event.FrameEventBinary;
import at.technikum_wien.embsys.aat.PriscillaCore.link.event.LinkListener;
import at.technikum_wien.embsys.aat.PriscillaCore.telegram.Telegram;



/**
 * 
 * EEP_07_30_02 component class - digital input
 *
 * Type: single input contact 
 * Single input contact
 * 
 * @author B. Aigner
 * 
 */
public class EEP_07_30_02 implements EnoceanComponent {
	
	Telegram telegram;
	List<?> eventListener;
	BinaryState contact = BinaryState.UNKNOWN;

	EnoceanComponentType enoceanComponentType = EnoceanComponentType.EEP_07_30_02;
	boolean telegramCreation = false;

	/**
	 * This constructor is used for received packets.
	 * It will parse the telegram and set the corresponding members.
	 * 
	 * @param telegram Received Telegram
	 * @param listener Event subscriber list
	 */
	public EEP_07_30_02(Telegram telegram, List<?> listener) {
		super();
		this.telegram = telegram;
		this.eventListener = listener;
		
		if (checkBit(telegram.getData0(), 0)) {
			contact = BinaryState.FALSE;
		} else {
			contact = BinaryState.TRUE;
		}
		
		fireFrame();
	}

	/**
	 * Fire all associated events
	 */
	void fireFrame() {
		Iterator<?> listen = eventListener.iterator();
		final FrameEventBinary frameEventBinary = new FrameEventBinary(this, telegram.getDeviceID(), this.contact, BinaryState.UNKNOWN, BinaryState.UNKNOWN, BinaryState.UNKNOWN);
		while (listen.hasNext()) {
			((LinkListener) listen.next()).frameReceived_Binary(frameEventBinary);
		}
	}

	/**
	 * Void constructor. It is used to create a new telegram for sending
	 */
	public EEP_07_30_02() {
		super();
		telegram = new Telegram();
		telegramCreation = true;
	}

	/**
	 * This constructor is used to create a telegram (the device id is given as parameter)
	 * @param deviceID Full device ID
	 */
	public EEP_07_30_02(String deviceID) {
		super();
		telegram = new Telegram();
		telegram.setDeviceID(deviceID);
		telegramCreation = true;
	}
	
	boolean checkBit(int value, int bitNr) {
		return (value & (1 << bitNr)) != 0;
	}
	
	int setBit(int value, int bitNr) {
		return value | (1<<bitNr);
	}
	
	int clrBit(int value, int bitNr) {
		return value & (~(1<<bitNr));
	}
	
	@Override
	public String getDeviceID() {
		return telegram.getDeviceID();
	}
	@Override
	public String getORG() {
		return telegram.getxORG();
	}
	@Override
	public EnoceanComponentType getType() {
		return enoceanComponentType;
	}

	@Override
	public void setDeviceID(String deviceID) {
		telegram.setDeviceID(deviceID);
	}

	/**
	 * Creates a new telegram from the component
	 * 
	 * This method creates a new telegram (if the component is initialized with
	 * a constructor without a telegram as parameter) or returns the saved telegram.
	 * The new telegram is built up from the members in this class (in this case input contact). 
	 * @return Created telegram
	 */
	public Telegram getTelegram() {
		if(telegramCreation == true) {
			if(contact == BinaryState.FALSE) {
				telegram.setData0(1);
			} else {
				telegram.setData0(0);
			}
		}
		return telegram;
	}

	public BinaryState getContact() {
		return contact;
	}

	public void setContact(BinaryState contact) {
		this.contact = contact;
	}
}
